///////List implementation using Linked list/////////////////////

#include <stdio.h>
#include <stdlib.h>

typedef struct node             //creating basic structure of linked list node
{
int value;

struct node *next;

}stnode;

int count=0; // global var to keep track of size of list

//*************************************************************************************************************//	

void addnode(stnode **list)             //adds a node at the end of the existing list
{
int num;
stnode *temp,*blist;
temp=(stnode *)malloc(sizeof(stnode));
blist=(stnode *)*list;
printf("Enter a value you want to enter in the list \n");

scanf("%d",&num);

temp->value=num;

	if ( *list== NULL)
	       {
	          *list=temp;
	          (*list)->next=NULL;
	       }

	else
	      {
	          while(blist->next!=NULL)
	          {
	          	blist=blist->next;
	          	
	          }
	          blist->next=temp;
	          temp->next=NULL;
	     }
	     
}

//*************************************************************************************************************//


void add2(stnode **list)       // adds a node at the beginning of the list..Though I have not used this function anywhere in the code.
{
int num;
stnode *temp;
temp=(stnode *)malloc(sizeof(stnode));

printf("Enter a value you want to enter in the list \n");

scanf("%d",&num);

temp->value=num;

	if ( *list== NULL)
	       {
	          *list=temp;
	          (*list)->next=NULL;
	       }

	else
	      {
	          temp->next=(*list);
	          (*list)=temp;
	     }
}

//*************************************************************************************************************//	

void create(stnode **list)  // creates the list initially
{

int a;
do 
{
addnode(list);
printf("Do you want to enter any more elements in the list? \n(Press 1 for Yes and 0 for No)\n");
scanf("%d",&a);
count=count+1;
}
while(a==1);
}


//*************************************************************************************************************//

void show(stnode **list)  //displays the elements of the list

{
stnode *temp;

temp=*list;

if(temp==NULL)
	{
		printf("List is empty !!\n");
	}

else
	{	
		
		printf("The list is : \n");
		printf("[");
		while(temp!=NULL)
		{
			printf("%d ",(temp)->value);
			temp=(temp->next);
			
		}
		printf("]\n");
		
	}
	
}


//*************************************************************************************************************//


void remove_x(stnode **list)   /// removes an element from the list

{
int x;
stnode *temp,*temp2;
printf("Enter the value you want to delete : \n");
scanf("%d",&x);
temp=*list;
while(temp->next!=NULL)
	{
		if(temp->value==x)
			{
           		if(temp==*list)
           			{
              			*list=temp->next;
              			free(temp);
           			}
           		else
         			{
           			temp2->next=temp->next;
           			free(temp);
         			}
      			}		
      		else
        		{
           		temp2=temp;
          		temp=temp->next;
        		}

	}
    printf("The value %d is not present in the list\n",x);
}

//*************************************************************************************************************//

void countlist() //returns the length of list
{
printf("The length of list is : %d \n",count);
}


//*************************************************************************************************************//

void rev(stnode **list)  //reverses the list
{

stnode *eena, *meena,*deeka;
eena= *list;
meena=NULL;
while(eena!=NULL)
	{
	deeka=meena;
	meena=eena;
	eena=eena->next;
	meena->next=deeka;
	}
*list=meena;
}


//*************************************************************************************************************//


void appendx(stnode **list) //appends the element at the end
{

addnode(list);
count=count+1;

printf("The value has been appended\n");

}


//*************************************************************************************************************//

//void insertx(stnode **list)  //inserts an element at the index provided by the user
//{
//int x,i,num;
//stnode *temp,*prev,*next;
//temp=(stnode *)malloc(sizeof(stnode));
//blist=(stnode *)*list;
//printf("Enter the index at which you want to insert the element :\n");
//scanf("%d",&x);
//printf("Enter the value you want to insert");
//scanf("%d",&num);
//temp->value=num;

//if(x<1 || x>count)
//	{
//		printf("Index value is invalid.Insertion not possible\n")
//	}
//else if (x==1)
//	{
//	        *list=temp;
//	        (*list)->next=NULL;
//		count=count+1;
//	}
//	
//else 
//	{
//	
//	for(i=1;i<x;i++)
//		{ *list->
//			

//}

//*************************************************************************************************************//

void extend_x(stnode **list)
{
int a;
do 
{
addnode(list);
printf("Do you want to enter any more elements in the list? \n(Press 1 for Yes and 0 for No)\n");
scanf("%d",&a);
count=count+1;
}
while(a==1);
}


//*************************************************************************************************************//

void insert_x(stnode **list)  //inserts the value at given index
	{
		int x,i,num;
		printf("Enter the index at which you want to insert the element :\n");
		scanf("%d",&x);
		printf("Enter the value that you wish to insert :\n");
		scanf("%d",&num);
		stnode *temp,*temp1;
		temp1=(stnode *)malloc(sizeof(stnode));
		if(x<1 || x>count)
			printf("Index value is invalid.Insertion not possible\n");
		else if ( x==1)
			{printf("The element has been inserted at index 1 in list\n");
			 temp1->value=num;
			 temp1->next=*list;
			 *list=temp1;	
			 count++;	
			}
		else
		{	x=x-1;			
			temp=*list;
			i=1;
			while(temp!=NULL)
			{
				
				if(x==i)
					{	
						temp1->value=num;	
						temp1->next=temp->next;	
						temp->next=temp1;		
						printf("The element has been inserted at index %d in your list\n" , i);
						count=count+1;
						break;
					}

				temp=temp->next;
				i++;
			}
			

		}



	}
	

//*************************************************************************************************************//


void pop(stnode **list)   // pops the value at given index
{
int x,i;
printf("Enter the index at which you want to pop the element :\n");
scanf("%d",&x);
	if(x<1 || x>count)
		printf("Index value is invalid.Insertion not possible\n");
	else if ( x==1)
		{printf("The element at position 1 has been popped from your list\n");
		 stnode *temp;
		 temp=*list;
		 *list=temp->next;
		 count=count-1;		
		}
	else
		{	
		x=x-1;	
		stnode *temp,*temp1;			
		temp=*list;
		i=1;
		while(temp->next!=NULL)
			{
			temp1=temp->next;
				if(x==i)
				{
					temp->next=temp1->next;			
					printf("The element at position %d has been popped from your list\n",x+1);
					break;
				}

			temp=temp->next;
			i++;
			}
		count=count-1;
		}
}




//*************************************************************************************************************//
void countx(stnode **list)       ///counts the no. of occurences of a value entered by user
{
int x,counter=0;
printf("Enter the value that you want to count\n");
scanf("%d",&x);

while((*list)->next!=NULL)
	{

		if((*list)->value==x)
			{
			counter=counter+1;
			}
		*list=(*list)->next;
	}
printf("The value %d appears %d times in the list\n",x,counter);
}


//*************************************************************************************************************//


void main() // Main Function
{
int opt;
stnode *B;                         //This contains the address of the first element of the linked list
B=NULL;

printf("This is Python's list data-type implementation using Linked list : \n\n\n\n");
create(&B);


do{

printf("________________________________________________________________\n");

printf("The options available are : \n");

printf("1. Display the list \n");

printf("2. Reverse the list \n");

printf("3. Append the list \n");

printf("4. Extend a list with a 2nd list \n");

printf("5. Count the no. of elements in the list \n");

printf("6. Count the no. of occurences of a value in the list \n");

printf("7. Remove an element from the list \n");

printf("8. Pop an element at a given index from the list \n");

printf("9. Insert an element at given index \n");

printf("10. Exit \n");

printf("________________________________________________________________\n");

printf("Enter your choice no. : \n");

scanf("%d",&opt);

switch(opt)
{
case 1 : show(&B);break;
case 2 : rev(&B);show(&B);break;
case 3 : appendx(&B);show(&B);break;
case 4 : extend_x(&B);show(&B);break;
case 5 : countlist();;break;
case 6 : countx(&B);break;
case 7 : remove_x(&B);show(&B);break;
case 8 : pop(&B);show(&B);break;
case 9 : insert_x(&B);show(&B);break;
case 10 : printf("Exiting.. !!");break;
default : printf("Invalid choice !!Please enter again. \n");break; 
}
}while (opt!=10);
}

//End of code
